class MyPromise {
  //函数构造器
  constructor(execute) {
    //初始promise状态
    this.state = "pending";
    //result为保存promise结果值
    this.result = null;
    //用于保存then中的onResolved回调
    this.onResolvedCallbacks = [];
    //用于保存then中的onRejected回调
    this.onRejectedCallbacks = [];
    try {
      //执行execute（执行器）
      execute(this.resolve, this.reject);
    } catch (err) {
      this.reject(err);
    }
  }
  //实现resolve
  resolve = (value) => {
    console.log('resolve', this.state, value);
    //加判断是因为promise状态只更改一次
    if (this.state === "pending") {
      //当状态为pending是修改为fulfilled
      this.state = "fulfilled";
      //保存成功promise的结果值
      this.result = value;
      //遍历保存的成功回调并调用再删除
      while (this.onResolvedCallbacks.length > 0) {
        this.onResolvedCallbacks.shift()();
      }
    }
  };
  //实现reject
  reject = (reason) => {
    console.log('reject', this.state, reason);
    if (this.state === "pending") {
      //当状态为pending是修改为reject
      this.state = "rejected";
      //保存失败promise的结果值
      this.result = reason;
      //遍历保存的成功回调并调用再删除
      while (this.onRejectedCallbacks.length > 0) {
        this.onRejectedCallbacks.shift()();
      }
    }
  };
  //实现then
  then(onResolve, onReject) {
    //判断onResolve是不是函数，如果不是则直接返回
    onResolve = typeof onResolve === "function" ? onResolve : (value) => value;
    //判断onReject是不是函数，如果不是则把传进来的参数直接扔出报错
    onReject =
      typeof onReject === "function"
        ? onReject
        : (reason) => {
            throw reason;
          };

    const MyPromise2 = new MyPromise((resolve, reject) => {
      try {
        //让then异步执行
        setTimeout(() => {
          //状态为fulfilled则执行成功回调
          if (this.state === "fulfilled") {
            //x获取onResolve的返回值
            let x = onResolve(this.result);
            //调用ResolvePromise并传入返回值x、resolve、reject与MyPromise2
            ResolvePromise(x, resolve, reject, MyPromise2);
          }
          //状态为rejected则执行失败回调
          else if (this.state === "rejected") {
            //x获取onReject的返回值
            let x = onReject(this.result);
            ResolvePromise(x, resolve, reject, MyPromise2);
          }
          //当状态为pending时则保存onResolve与onReject
          else if (this.state === "pending") {
            this.onResolvedCallbacks.push(() => {
              let x = onResolve(this.result);
              ResolvePromise(x, resolve, reject, MyPromise2);
            });

            this.onRejectedCallbacks.push(() => {
              let x = onReject(this.result);
              ResolvePromise(x, resolve, reject, MyPromise2);
            });
          }
        }, 0);
        //ResolvePromise是用来判断onResolve与onReject的返回值并做出处理
        const ResolvePromise = (x, resolve, reject, promise2) => {
          //如果x等于then的返回值则扔出报错
          if (x === promise2) {
            throw new Error("不能返回自身");
          }
          //如果x是MyPromise实例，则使用.then方法来获取MyPromise的结果
          if (x instanceof MyPromise) {
            x.then(
              (res) => {
                resolve(res);
              },
              (err) => {
                reject(err);
              }
            );
          }
          //如果不是MyPromise实例则直接resolve
          else {
            resolve(x);
          }
        };
      } catch (err) {
        reject(err);
        throw new Error(err);
      }
    });
    return MyPromise2;
  }
  //实现catch
  catch(onReject) {
    //判断onReject是不是函数，如果不是则把传进来的参数直接扔出报错
    onReject =
      typeof onReject === "function"
        ? onReject
        : (reason) => {
            throw reason;
          };

    const MyPromise2 = new MyPromise((resolve, reject) => {
      try {
        //让then异步执行
        setTimeout(() => {
          //状态为rejected则执行失败回调
          if (this.state === "rejected") {
            //x获取onReject的返回值
            let x = onReject(this.result);
            ResolvePromise(x, resolve, reject, MyPromise2);
          }
          //当状态为pending时则保存onResolve与onReject
          else if (this.state === "pending") {
            this.onRejectedCallbacks.push(() => {
              let x = onReject(this.result);
              ResolvePromise(x, resolve, reject, MyPromise2);
            });
          }
        }, 0);
        //ResolvePromise是用来判断onResolve与onReject的返回值并做出处理
        const ResolvePromise = (x, resolve, reject, promise2) => {
          //如果x等于then的返回值则扔出报错
          if (x === promise2) {
            throw new Error("不能返回自身");
          }
          //如果x是MyPromise实例，则使用.then方法来获取MyPromise的结果
          if (x instanceof MyPromise) {
            x.then(
              (res) => {
                resolve(res);
              },
              (err) => {
                reject(err);
              }
            );
          }
          //如果不是MyPromise实例则直接resolve
          else {
            resolve(x);
          }
        };
      } catch (err) {
        reject(err);
        throw new Error(err);
      }
    });
    return MyPromise2;
  }

  //promise resolve方法
  static resolve(value) {
    return new MyPromise((resolve) => {
      resolve(value);
    });
  }
  //promise reject方法
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }
  //promise all方法
  static all(promises) {
    //保存成功结果
    let success = [];
    //记录保存数量
    let count = 0;
    //返回一个Promise
    return new MyPromise((resolve, reject) => {
      //保存成功的结果
      const save = (value, index) => {
        //用index保存是为了与promises的顺序一致
        success[index] = value;
        // 记录保存数量
        count++;
        //当保存数量与promises一致时说明所有结果都为成功直接resolve
        if (count === promises.length) resolve(success);
      };
      try {
        // 遍历promises
        promises.forEach((promise, index) => {
          //判断promise中的每一项是不是MyPromise的实例
          if (promise instanceof MyPromise) {
            promise.then(
              (res) => {
                //成功的promise则保存结果
                save(res, index);
              },
              (err) => {
                //失败的直接reject
                reject(err);
              }
            );
          } else {
            //不是MyPromise直接为成功进行保存
            save(promise, index);
          }
        });
      } catch (err) {
        reject(err);
        throw new Error(err);
      }
    });
  }
  //promise race方法
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      try {
        // 遍历promises
        promises.forEach((promise) => {
          //判断promise中的每一项是不是MyPromise的实例
          if (promise instanceof MyPromise) {
            promise.then(
              (res) => {
                resolve(res);
              },
              (err) => {
                //失败的直接reject
                reject(err);
              }
            );
          } else {
            resolve(promise);
          }
        });
      } catch (err) {
        reject(err);
        throw new Error(err);
      }
    });
  }
  // Promise allSettled方法
  static allSettled(promises) {
    //保存结果
    let result = [];
    //记录保存数量
    let count = 0;
    //返回一个Promise
    return new MyPromise((resolve, reject) => {
      //保存成功的结果
      const save = (value, index, state) => {
        //用index保存是为了与promises的顺序一致
        result[index] = {
          value,
          state,
        };
        // 记录保存数量
        count++;
        //当保存数量与promises一致时说明所有结果都为成功直接resolve
        if (count === promises.length) resolve(result);
      };
      try {
        // 遍历promises
        promises.forEach((promise, index) => {
          //判断promise中的每一项是不是MyPromise的实例
          if (promise instanceof MyPromise) {
            promise.then(
              (res) => {
                //保存promise的结果
                save(res, index, "fulfilled");
              },
              (err) => {
                save(err, index, "rejected");
              }
            );
          } else {
            //不是MyPromise直接为成功进行保存
            save(promise, index, "fulfilled");
          }
        });
      } catch (err) {
        reject(err);
        throw new Error(err);
      }
    });
  }
}
/**
 * 简单的Promise
 * @param {*} fn 传递执行方法参数
 */
const SimplePromise = function(fn) {
  let self = this
  self.status = "pending"
  self.value = null
  self.reason = null

  // 解决异步请求
  self.onResolvedCallbacks = []
  self.onRejectedCallbacks = []

  /**
   * 成功
   * @param {*} value 
   */
  function resolve(value) {
    if (self.status === 'pending') {
      self.value = value
      self.status = "fulfilled"
      self.onResolvedCallbacks.forEach(item => item(value))
    }
  }
  /**
   * 失败
   * @param {*} value 
   */
  function reject(value) {
    if (self.status === 'pending') {
      self.reason = value
      self.status = "rejected"
      self.onRejectedCallbacks.forEach(item => item(value))
    }
  }

  // 执行函数
  fn(resolve, reject)

  SimplePromise.prototype.then = function(onFulfilled, onRejected) {
    // 三元判断
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (data) {
      resolve(data)
    }

    onRejected = typeof onRejected === 'function' ? onRejected : function (err) {
      throw err
    }

    let self = this
    if (self.status === 'pending') {
      // 通常then会返回两个参数.then(res => console.log(res), err => console.log(err))
      self.onResolvedCallbacks.push(onFulfilled)
      self.onRejectedCallbacks.push(onRejected)
    }
  }
}

// function NewPromise(executor) {
//   var self = this
//   self.status = 'pending'
//   self.data = undefined
//   // Promise resolve时的回调函数集，因为在Promise结束之前有可能有多个回调添加到它上面
//   self.onResolvedCallback = []
//   // Promise reject时的回调函数集，因为在Promise结束之前有可能有多个回调添加到它上面
//   self.onRejectedCallback = []

//   // 执行内部方法
//   function resolve(value) {
//     // TODO
//     if (self.status === 'pending') {
//       self.status = 'fulfilled'
//       self.data = value
//       self.onResolvedCallback.forEach(item => item(value))
//     }
//   }

//   function reject(reason) {
//     // TODO
//     if (self.status === 'pending') {
//       self.status = 'rejected'
//       self.data = reason
//       self.onRejectedCallback.forEach(item => item(reason))
//     }
//   }
  
//   // 需要在原型上挂在then函数方法
//   // then方法接收两个参数，onFulfilled，onRejected分别为Promise成功或失败后的回调
//   NewPromise.prototype.then = (onFulfilled, onRejected) {
//     let self = this
//     onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
//     onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

//     if (this.PromiseState === 'fulfilled') {
//         // 如果当前为成功状态，执行第一个回调
//         onFulfilled(self.data)
//     } else if (this.PromiseState === 'rejected') {
//         // 如果当前为失败状态，执行第二哥回调
//         onRejected(self.data)
//     }
//     if (self.status === 'pending') {
//       self.onResolvedCallbacks.push(onFulfilled)
//       self.onRejectedCallbacks.push(onRejected)
//     }

//   }

//   try {
//     // 正常初始化resolve和reject，这两个参数目前还没有定义，执行的是resolve，reject内部的方法
//     executor(resolve, reject)
//   } catch (error) {
//     reject(error)
//   }
// }
export { MyPromise, SimplePromise };
